package com.cskaoyan.javase.oop1._1basic;

/**
 * 对象与类的基础案例，创建学生对象
 * 要想创建学生对象，首先需要创建对象的"模板"——学生类，那么如何得到一个学生类呢？
 *
 * 如何定义类？
 * 定义类包括定义类本身，和定义类中结构两部分。
 *
 * 1.定义一个类
 *      类的定义语法我们并不陌生，即：
 *      [类修饰符列表] class 类名{
 *          // 类体
 *      }
 *
 * 语法解释：
 *      1.对于类的修饰符列表，可以有很多，但是限于学习进度，我们只需要知道：
 *          一个Java文件中只能定义一个public修饰的类，但是可以定义多个非public类。
 *          这些多个非public class和public class，它们之间是什么关系？
 *          这些类都是同包的关系，而同包下不允许出现同名类
 *
 *      2.类名应该遵循大驼峰式的命名规范，类既然是描述个体的模板，一般多使用名词。最好见名知意。
 *
 *      3.在局部位置中定义的变量是局部变量
 *        局部位置主要包括：方法体，类体中的大括号，以及这些结构中嵌套的大括号内部。
 *      类体：虽然也是一个大括号，但是类体中不是局部位置。在类体中直接定义的变量也不是局部变量。
 *
 *      约定：
 *      在实际开发中，绝大多数情况下，一个Java文件里往往都只有一个和文件名相同的public class。
 *       但为了上课方便，避免切换Java文件导致的麻烦，我们约定：
 *       以一个public class作为测试类，然后在下面定义非public class用于测试！
 *
 *       注意事项：
 *       Java中的类是可以嵌套定义的，即你可以把一个class定义进另一个类的类体中！这种类被称之为"内部类"！
 *       内部类的语法你完全没有学过，请大家不要定义内部类
 *       在定义类时，请大家认真的看清楚类体的大括号范围，不要嵌套定义类。
 *
 *
 * 以上定义完了一个的类，现在开始定义类中的结构，来定义创建对象的模板
 * 类是抽象的，类描述了全体对象的共性属性的行为特征。、
 * 既然类是创建对象的"模板"，那么就应该能够描述一种类别的全体对象，所以：
 *      1.我们抽象对象全体的共有"属性"，在类中用成员变量来描述对象共性的属性。
 *          何为成员变量?
 *              成员变量类似于局部变量,是按照在内存中的位置/代码中的定义位置的不同,所分类的变量类型.
 *              局部变量定义在局部位置,成员变量定义在成员位置
 *              成员位置: 类体中,非局部位置,都是成员位置
 *
 *          定义成员变量的语法：
 *          [修饰符列表] 数据类型 成员变量名;
 *              a.可以修饰成员变量的修饰符有很多，现在我们先默认它什么都不写，保持空着。
 *              b.成员变量的数据类型,可以是基本数据类型,也可以是引用数据类型.
 *
 *      2.我们抽象对象全体的共有"行为"，在类中用成员方法来描述对象共性的行为。
 *      成员方法: 指的是定义在类体中的成员位置,但是修饰符列表中没有static修饰的方法.
 *      语法:
 *      [访问权限修饰符] 返回值类型 方法名(形参列表){
 *          // 方法体
 *      }
 *      解释:
 *          a.成员方法和我们之前学习的方法,就是少一个static修饰
 *          b.访问权限修饰符,我们还没有学习,先默认它是public.
 *          c.除以上没有static修饰外,返回值类型,方法名,形参,方法体等和static方法没有区别
 *
 *      以上就把创建对象的模板,类,定义完了.
 *      接下来,就需要用这个模板来创建对象,使用对象完成一系列操作
 *
 * 根据类来创建对应数据类型的对象:
 * 创建类的对象一般需要在方法中进行，在确定能够创建对象的地方(如果两个类之间是同包的关系,那么可以任意创建对象)，可以使用以下语法创建对象：
 *      类名 对象名 = new 类名();
 *      解释:
 *
 *      1.类名表示创建是何种对象，对象的类型是什么。一般来说,左右两边的类名是需要保持一致的.
 *
 *      2.对象名和之前讲的数组名是同一个概念，都是引用数据类型的引用。作为一个变量名，对象名遵循小驼峰式的命名规范。
 *      所以该条语句也是创建了一个引用数据类型的变量,是引用 + 对象
 *      如果该条语句处在局部位置,那么就是创建了一个局部变量,引用存在方法的栈帧中.
 *
 *      3.new关键字表示在堆上开辟空间创建对象，注意代码中的new关键字表示一定会在堆上创建一个独立的对象。
 *
 *      4.对象是实质,但是我们只能通过引用间接的访问对象.引用中通过存储堆上对象的地址,和堆上的对象产生联系.
 *
 * 对象创建完毕后,开始使用这个对象:
 *      1.如何访问对象的属性呢?
 *      在同包下,访问同包中类创建的对象的属性
 *      如果该类中的成员变量的修饰符为空
 *      那么,就可以直接用"对象名.成员变量名"访问
 *      同样也可以用于赋值.
 *
 *      (重点)对象中的成员变量,是直接存储在对象中的,它具有默认初始化(而且必然是最先进行的赋值手段),
 *      它具有默认值
 *      这一点和数组中元素的取值一样
 *      默认值也是一样的
 *
 *
 *      2.如何去调用对象中的成员方法?
 *      public修饰的成员方法,可以直接用"对象名.成员方法名(实参)"来调用成员方法
 *
 *
 * 总结:
 *      无论是成员变量,还是成员方法,它们的使用/调用,都必须使用一个对象
 *      如果没有对象,成员变量/方法是不可用的
 *      成员变量/方法,统称类的成员
 *      它们是属于对象(重点)
 *
 *
 *
 *
 *
 * @since 16:14
 * @author wuguidong@cskaoyan.onaliyun.com
 */
// Demo类用于做测试类
public class Demo {

    // 成员位置
    public static void main(String[] args) {
        // 在main方法中创建Student类的对象
        Student s = new Student();
        System.out.println(s.name);
        System.out.println(s.age);
        System.out.println(s.stuId);
        System.out.println(s.score);
        s.name = "张三";
        System.out.println(s.name);

        s.study();
        s.sleep();
        s.eat();

        /*
        直接输出对象名,得出以下字符串:
            com.cskaoyan.javase.oop1._1basic.Student@1540e19d

            首先打印该对象的类型的全限定类名
            @后面跟的是一个十六进制的地址值
            强调: 这个结果是可以修改的
                比如String,直接打印String的对象引用
                就会得到这个字符串
         */
        System.out.println(s);

        // new关键字表示创建对象,而且是一定创建一个新的独立的对象
        Student s2 = new Student();
        // "=="比较地址,很明显,s和s2指向的不是同一个对象,返回false
        System.out.println(s == s2);
        System.out.println(s2);
        s.score = 100;
        System.out.println(s2.score);
    }
    /*class Student {

    }*/
}

// 定义一个学生类
class Student {
    // 成员位置
    // 在类体中成员位置定义成员变量,用来描述全体学生对象的共性"属性"特征
    String name;
    int age;
    int stuId;
    double score;

    // 在类体中成员位置定义成员方法,用来描述全体学生对象的共性"行为"特征
    public void study() {
        System.out.println("学习多是一件美事~");
    }

    public void eat() {
        // System.out.println("这碗鸡汤,非常的珍贵,请同志们先喝!");
        System.out.println("鸡汤来咯~~");
    }

    public void sleep() {
        System.out.println("你这么睡得着的?你这个年龄段~~~");
    }
    // public int _3test(int a){
    //     return 0;
    // }


}